package com.lanyu.community.api.aop;


import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
 
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
 
/**
 * @author suibin
 */
@Slf4j
@Component
//@Aspect
public class WebAspect {
    @Resource
    private HttpServletRequest request;
    /*
    整个表达式可以分为五个部分：

    1、execution(): 表达式主体。

    2、第一个*号：表示返回类型，*号表示所有的类型。

    3、包名：表示需要拦截的包名，后面的两个句点表示当前包和当前包的所有子包，com.sample.service.impl包、子孙包下所有类的方法。

    4、第二个*号：表示类名，*号表示所有的类。

    5、*(..):最后这个星号表示方法名，*号表示所有的方法，后面括弧里面表示方法的参数，两个句点表示任何参数。
    */
    @Pointcut("execution(public * com.lanyu.community.api.controller.*.*(..))")
    public void webLog() {
    }
 
    /**
     * 前置通知
     */
    @Before("webLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        System.out.println("前置通知 = " + joinPoint);
    }
 
 
    /**
     * 声明环绕通知
     */
    @Around("webLog()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("进入方法---环绕通知");
        // 记录下请求内容
        log.info("URL : " + request.getRequestURL().toString());
        log.info("HTTP_METHOD : " + request.getMethod());
        log.info("IP : " + request.getRemoteAddr());
        log.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
        log.info("ARGS : " + Arrays.toString(joinPoint.getArgs()));
        return joinPoint.proceed();
    }


    /**
     * 声明例外通知
     */
    @AfterThrowing(pointcut = "webLog()", throwing = "e")
    public void doAfterThrowing(Exception e) {
        System.out.println("例外通知");
        System.out.println(e.getMessage());
    }
 
    /**
     * 声明最终通知
     */
    @After("webLog()")
    public void doAfter() {
        System.out.println("最终通知");
    }
 
    /**
     * 声明后置通知
     */
    @AfterReturning(pointcut = "webLog()", returning = "result")
    public void doAfterReturning(String result) {
        System.out.println("后置通知");
        System.out.println("---" + result + "---");
    }
 
 
}